#include "model/datacenter.h"
#include "mainwidget.h"
#include "messageeditarea.h"
#include "soundrecorder.h"
#include "toast.h"

MessageEditArea::MessageEditArea(QWidget *parent)
    : QWidget{parent}, m_sendImageBtn(new QPushButton()), m_sendSpeechBtn(new QPushButton()),
    m_sendFileBtn(new QPushButton()), m_showHistoryBtn(new QPushButton()),m_tipLabel(new QLabel("录音中..."))
{
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    // this->setStyleSheet("QWidget{border: 1px solid rgb(231,231, 231);}");  // 为什么和toolsContainer是一样的大小？
    setFixedHeight(200);

    // 主编辑窗口为 垂直+水平
    QVBoxLayout* vlayout = new QVBoxLayout();
    this->setLayout(vlayout);

    // 1.工具窗口（水平）
    QWidget* toolsContainer = new QWidget();
    vlayout->addWidget(toolsContainer);

    QHBoxLayout* toolLayout = new QHBoxLayout();
    toolsContainer->setLayout(toolLayout);
    toolLayout->setContentsMargins(0, 10, 0, 0);
    toolLayout->setSpacing(10);
    toolLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop);

    QIcon image(":/resource/image/image.png");
    QIcon speech(":/resource/image/sound.png");
    QIcon file(":/resource/image/file.png");
    QIcon history(":/resource/image/history.png");
    QList<QIcon> iconList = {image, speech, file, history};

    QString buttonStyle = "QPushButton { background-color: transparent; border: none; } "
                          "QPushButton:pressed { background-color: #E1DFDE;}";

    QList<QPushButton*> listBtn = {m_sendImageBtn, m_sendSpeechBtn, m_sendFileBtn, m_showHistoryBtn};
    int index = 0;
    for(auto& pbtn : listBtn){
        pbtn->setFixedSize(20, 20);
        pbtn->setIconSize(QSize(20, 20));
        pbtn->setIcon(iconList[index++]);
        pbtn->setStyleSheet(buttonStyle);
        pbtn->setCursor(Qt::PointingHandCursor);
        toolLayout->addWidget(pbtn);
    }

    // 录制时的提示
    m_tipLabel->setFont(QFont("微软雅黑", 24));
    m_tipLabel->hide();
    vlayout->addWidget(m_tipLabel, 0, Qt::AlignHCenter);


    // 2.添加多行编辑框
    m_textEdit = new QPlainTextEdit();
    m_textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_textEdit->setStyleSheet("QPlainTextEdit {font-size: 16px; background-color: transparent; border: none; }");
    // 把垂直滚动条设置的细⼀些.
    m_textEdit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(231, 231, 231); }"
                                                   "QScrollBar::handle:vertical {background-color: rgb(178, 178, 178);}");
    vlayout->addWidget(m_textEdit);

    // 3.添加发送消息按钮
    m_sendBtn = new QPushButton("发送");
    m_sendBtn->setStyleSheet("QPushButton {font-size: 16px; color: #27C160; background-color: #E9E9E9; border:none; border-radius: 5px;}"
                             "QPushButton:hover { background-color: #D2D2D2;}"
                             "QPushButton:pressed { background-color: #C6C6C6;}");
    m_sendBtn->setFixedSize(100, 30);
    vlayout->addWidget(m_sendBtn, 0, Qt::AlignRight);

    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::sendMessageDone, this, &MessageEditArea::addSelfMessage);
    connect(dataCenter, &model::DataCenter::receiveMessageDone, this, &MessageEditArea::addOtherMessage);
    // 初始化各个按钮的信号槽
    PushButtonsSlot();
}

void MessageEditArea::PushButtonsSlot()
{
    // 历史消息展示
    connect(m_showHistoryBtn, &QPushButton::clicked, this, [=]{
        auto dataCenter = model::DataCenter::getInstance();
        if(dataCenter->getCurrentChatSessionId().isEmpty()){
            LOG() << "会话未选中";
            return ;
        }
        HistoryMessageWidget* dialog = new HistoryMessageWidget();
        dialog->exec();
    });

    // 发送消息按钮
    connect(m_sendBtn, &QPushButton::clicked, this, &MessageEditArea::sendTextMessage);
    // 发送图片按钮
    connect(m_sendImageBtn, &QPushButton::clicked, this, &MessageEditArea::sendImageMessage);
    // 发送文件按钮
    connect(m_sendFileBtn, &QPushButton::clicked, this, &MessageEditArea::sendFileMessage);
    // 发送语音按钮
    connect(m_sendSpeechBtn, &QPushButton::pressed, this, &MessageEditArea::soundRecordPressed);
    connect(m_sendSpeechBtn, &QPushButton::released, this, &MessageEditArea::soundRecordReleased);
}
/////////////////////////////////////////////////
/////////////////// 槽函数 ///////////////////////
/////////////////////////////////////////////////
void MessageEditArea::sendTextMessage()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1.会话列表没有被选中
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        Toast::showMessage("当前会话未选中");
        return ;
    }

    // 2.编辑框里没有内容
    QString content = m_textEdit->toPlainText().trimmed();
    if(content.isEmpty()){
        Toast::showMessage("不能发送空白消息");
        return ;
    }

    // 3. 置空
    m_textEdit->setPlainText("");

    // 4. 通过⽹络发送数据给服务器
    dataCenter->sendMessageAsync(dataCenter->getCurrentChatSessionId(), content);
}

void MessageEditArea::sendImageMessage()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1.会话列表没有被选中
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        Toast::showMessage("当前会话未选中");
        return ;
    }

    // 打开图片文件
    QString filter = "Image Files (*.png *.jpg *.jpeg *.bmp)";
    QString imagePath = QFileDialog::getOpenFileName(this, "打开图片", QDir::homePath(), filter);
    if(imagePath.isEmpty()){
        LOG() << "图片取消发送";
        return ;
    }
    QByteArray content = model::loadImageToByteArray(imagePath);
    dataCenter->sendImageMessageAsync(dataCenter->getCurrentChatSessionId(), content);
}

void MessageEditArea::sendFileMessage()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1.会话列表没有被选中
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        Toast::showMessage("当前会话未选中");
        return ;
    }

    // 打开文件
    QString filter = "*";
    QString filePath = QFileDialog::getOpenFileName(this, "打开文件", QDir::homePath(), filter);
    if(filePath.isEmpty()){
        LOG() << "文件取消发送";
        return ;
    }
    QFileInfo fileInfo(filePath);
    QString fileName = fileInfo.fileName();
    QByteArray content = model::loadFiletoByteArray(filePath);
    LOG() << "文件名：" << fileName;
    dataCenter->sendFileMessageAsync(dataCenter->getCurrentChatSessionId(), fileName, content);
}

void MessageEditArea::soundRecordPressed()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1.会话列表没有被选中
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        Toast::showMessage("当前会话未选中");
        return ;
    }

    // 2.更换图标
    m_sendSpeechBtn->setIcon(QIcon(":/resource/image/sound_active.png"));
    m_textEdit->hide();
    m_tipLabel->show();

    // 3.开始录音
    auto sound = SoundRecorder::getInstance();
    sound->startRecord();
}

void MessageEditArea::soundRecordReleased()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1.会话列表没有被选中
    if(dataCenter->getCurrentChatSessionId().isEmpty()){
        Toast::showMessage("当前会话未选中");
        return ;
    }

    // 更换图标
    m_sendSpeechBtn->setIcon(QIcon(":/resource/image/sound.png"));
    m_textEdit->show();
    m_tipLabel->hide();

    // 3.停止录音
    auto sound = SoundRecorder::getInstance();
    sound->stopRecord();

    // 4.发送网络请求
    QByteArray content = model::loadFiletoByteArray(sound->RECORD_PATH);
    dataCenter->sendSpeechMessageAsync(dataCenter->getCurrentChatSessionId(), content);
}

void MessageEditArea::addSelfMessage(model::MessageType messageType, const QByteArray &content, const QString &extraInfo)
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    // 1.构造消息对象, 并添加到消息列表中
    Message message = Message::makeMessage(*dataCenter->getMyself(), dataCenter->getCurrentChatSessionId(),
                                                  messageType, content, extraInfo);
    dataCenter->addMessage(message);
    message.m_fileName = extraInfo;

    // 2.把消息展示出来
    MainWidget* mainwidget = MainWidget::getInstance();
    MessageShowArea* msgShowArea = mainwidget->getMessageShowArea();
    msgShowArea->addMessage(false, message);

    // 3.控制滚动条到最下面
    msgShowArea->scrollToEndLater();

    // 4.更新窗口实时消息
    emit dataCenter->updateLastMessage(dataCenter->getCurrentChatSessionId());
}

void MessageEditArea::addOtherMessage(const Message &msg)
{
    // 1.把消息展示出来
    MainWidget* mainwidget = MainWidget::getInstance();
    MessageShowArea* msgShowArea = mainwidget->getMessageShowArea();
    msgShowArea->addMessage(true, msg);

    // 2.控制滚动条到最下面
    msgShowArea->scrollToEndLater();

    // 3.更新窗口的消息放在外面，这里提示一下添加完毕
    Toast::showMessage(QString("成功接受一条, msg:%1").arg(msg.m_content));
}
